#ifndef __SYSDEF_H_
#define __SYSDEF_H_

#define __SYS_write         1
#define __SYS_read          2
#define __SYS_fork          3
#define __SYS_yield         4
#define __SYS_wait          5
#define __SYS_exit          6
#define __SYS_getpid        7
#define __SYS_open          8
#define __SYS_pause         9
#define __SYS_waitpid       10
#define __SYS_chdir         11
#define __SYS_fsync         12
#define __SYS_readdir       13
#define __SYS_dup           14
#define __SYS_dup2          15
#define __SYS_getcwd        16
#define __SYS_rename        17
#define __SYS_mount         18
#define __SYS_umount        19
#define __SYS_mkdir         20
#define __SYS_rmdir         21
#define __SYS_lseek         22
#define __SYS_sleep         23
#define __SYS_fchdir        24
#define __SYS_realpathof    25
#define __SYS_swapon        26
#define __SYS_execve        27
#define __SYS_mmap          28
#define __SYS_time          29

#define RET_STATUS(errno) (cur_proc->k_status = errno)

#define __SYSCALL0(ftype, fname) \
static ftype fname() { \
long __res; \
asm volatile ("int $0x80" \
    : "=a" (__res) \
    : "a" (__SYS_##fname)); \
return (ftype) __res; \
}

#define __DEF_SYSCALL0(ftype, fname) \
ftype sys_##fname()

#define __SYSCALL1(ftype, fname, p1type, p1) \
static ftype fname(p1type p1) { \
long __res; \
asm volatile ("int $0x80" \
    :"=a"(__res) \
    :"0"(__SYS_##fname), "b" ((long)(p1))); \
return (ftype) __res; \
}

#define __DEF_SYSCALL1(ftype, fname, p1type, p1) \
ftype sys_##fname(p1type p1)

#define __SYSCALL2(ftype, fname, p1type, p1, p2type, p2) \
static ftype fname(p1type p1, p2type p2) { \
long __res; \
asm volatile ("int $0x80" \
    :"=a"(__res) \
    :"0"(__SYS_##fname), "b"((long)(p1)), "c" ((long)(p2))); \
return (ftype) __res; \
}

#define __DEF_SYSCALL2(ftype, fname, p1type, p1, p2type, p2) \
ftype sys_##fname(p1type p1, p2type p2)

#define __SYSCALL3(ftype, fname, p1type, p1, p2type, p2, p3type, p3) \
static ftype fname(p1type p1, p2type p2, p3type p3) { \
long __res; \
asm volatile ("int $0x80" \
    :"=a"(__res) \
    :"0"(__SYS_##fname), "b"((long)(p1)), "c"((long)(p2)), "d"((long)(p3))); \
return (ftype) __res; \
}

#define __DEF_SYSCALL3(ftype, fname, p1type, p1, p2type, p2, p3type, p3) \
ftype sys_##fname(p1type p1, p2type p2, p3type p3)

#define __SYSCALL4(ftype, fname, p1type, p1, p2type, p2, p3type, p3, p4type, p4) \
static ftype fname(p1type p1, p2type p2, p3type p3, p4type p4) { \
long __res; \
asm volatile ("int $0x80" \
    :"=a"(__res) \
    :"0"(__SYS_##fname), "b"((long)(p1)), "c"((long)(p2)), "d"((long)(p3)), "S"((long)(p4))); \
return (ftype) __res; \
}

#define __DEF_SYSCALL4(ftype, fname, p1type, p1, p2type, p2, p3type, p3, p4type, p4) \
ftype sys_##fname(p1type p1, p2type p2, p3type p3, p4type p4)

#define __SYSCALL5(ftype, fname, p1type, p1, p2type, p2, p3type, p3, p4type, p4, p5type, p5) \
static ftype fname(p1type p1, p2type p2, p3type p3, p4type p4, p5type p5) { \
long __res; \
asm volatile ("int $0x80" \
    :"=a"(__res) \
    :"0"(__SYS_##fname), "b"((long)(p1)), "c"((long)(p2)), "d"((long)(p3)), "S"((long)(p4)), "D"((long)(p5))); \
return (ftype) __res; \
}

#define __DEF_SYSCALL5(ftype, fname, p1type, p1, p2type, p2, p3type, p3, p4type, p4, p5type, p5) \
ftype sys_##fname(p1type p1, p2type p2, p3type p3, p4type p4, p5type p5)

#define __SYSCALL6(ftype, fname, p1type, p1, p2type, p2, p3type, p3, p4type, p4, p5type, p5, p6type, p6) \
static ftype fname(p1type p1, p2type p2, p3type p3, p4type p4, p5type p5, p6type p6) { \
long __res; \
asm volatile ("int $0x80" \
    :"=a"(__res) \
    :"0"(__SYS_##fname), "b"((long)(p1)), "c"((long)(p2)), "d"((long)(p3)), "S"((long)(p4)), "D"((long)(&p5))); \
return (ftype) __res; \
}

// p5 and p6 need to be fetched via va_arg, so put them in the args list as a hint
#define __DEF_SYSCALL6(ftype, fname, p1type, p1, p2type, p2, p3type, p3, p4type, p4, p5type, p5, p6type, p6) \
ftype sys_##fname(p1type p1, p2type p2, p3type p3, p4type p4, va_list __args)

#endif // __SYSDEF_H_